package com.swak.monitor.telnet.service;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.swak.App;
import com.swak.Constants;
import com.swak.OS;
import com.swak.registry.NotifyListener;
import com.swak.registry.RegistryService;
import com.swak.registry.URL;
import com.swak.telnet.Telnet;
import com.swak.telnet.invoker.TelnetInvoker;
import com.swak.utils.Maps;

@Service
public class TelnetService implements InitializingBean, DisposableBean, NotifyListener {

	private URL url;

	@Autowired(required = false)
	private RegistryService registryService;

	@Autowired
	private App app;

	private final Map<URL, TelnetInvoker> invokers = Maps.newConcurrentMap();

	public TelnetService() {
	}

	public Set<URL> telnets() {
		return invokers.keySet();
	}

	@Override
	public synchronized void notify(List<URL> urls) {

		// new invokers
		Map<URL, TelnetInvoker> newInvokers = Maps.newHashMap();
		for (URL url : urls) {
			TelnetInvoker invoker = invokers.get(url);
			if (invoker == null) {
				invoker = Telnet.getInstance().newTelnetInvoker(url);
			}
			newInvokers.put(url, invoker);
		}

		// destroy invoker
		for (URL url : invokers.keySet()) {
			if (newInvokers.get(url) != null) {
				continue;
			}
			try {
				TelnetInvoker invoker = invokers.get(url);
				invoker.destroy();
			} catch (Exception e) {
			}
		}

		// set new invokers
		invokers.clear();
		invokers.putAll(newInvokers);
	}

	@Override
	public void destroy() throws Exception {
		if (this.registryService != null) {
			this.registryService.unsubscribe(this.url, this);
		}
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		if (this.registryService != null) {
			Map<String, String> parameters = Maps.newHashMap();
			parameters.put(Constants.Application_KEY, app.getName());
			parameters.put(Constants.Category_Key, Constants.Registry_Telnet_Server_Key);
			this.url = new URL(Constants.Registry_Telnet_Key, OS.ip(), 0, parameters);
			this.registryService.subscribe(this.url, this);
		}
	}
}
